﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Linq.Expressions;
using System.Threading;

namespace Numercial_Analysis
{
    public static class StringExtensions
    {
        public static IEnumerable<string> SplitAndKeep(this string s, char[] delims)
        {
            int start = 0;
            int index = 0;

            while ((index = s.IndexOfAny(delims, start)) != -1)
             {
                index++;
                index = Interlocked.Exchange(ref start, index);

                yield return s.Substring(index, start - index - 1);
                yield return s.Substring(start - 1, 1);
             }

             if (start < s.Length)
             {
                yield return s.Substring(start);
             }
        }
    }

    class Equation
    {
        private Expression<Func<double, double>> equat;
        private String express;
        private char[] sep = { '+', '*', '/', '-', '^', '(', ')', '[', ']', 'x', 'y', 'z', 'X', 'Y', 'Z' };

        public Equation(Expression<Func<double, double>> func)
        {
            equat = func;
        }

        public Equation(String equation)
        {
            String retVal = stringToEquation(equation);
            if (retVal.CompareTo("Pass") != 0)
            {
                throw new System.InvalidOperationException(retVal);
            }
        }

        private String stringToEquation(String val)
        {
            String retVal = "Pass";
            express = val;
            bool mult = false;
            double num;
            foreach (string parts in StringExtensions.SplitAndKeep(val, sep))
            {
                if (parts.IndexOf("cos") != -1)
                {

                }
                else if (parts.IndexOf("sin") != -1)
                {

                }
                else if (parts.IndexOf("e") != -1)
                {

                }
                else if (parts.IndexOf("tan") != -1)
                {

                }
                else if (parts.IndexOf("sec") != -1)
                {

                }
                else if (parts.IndexOf("csc") != -1)
                {

                }
                else if (parts.IndexOf("sqrt") != -1)
                {

                }
                else if (parts.IndexOf("x") != -1 || parts.IndexOf("X")!=-1)
                {

                }
                else if (parts.IndexOf("y") != -1 || parts.IndexOf("Y")!=-1)
                {

                }
                else if (parts.IndexOf("z") != -1 || parts.IndexOf("Z")!=-1)
                {

                }
                else if (double.TryParse(parts, out num))
                {

                }
                else
                {
                    if (mult)
                    {
                        retVal += " and " + parts;
                    }
                    else
                    {
                        retVal = "Fail at " + parts;
                        mult = true;
                    }
                }
            }
            return retVal;
        }

        public double evalAt(double val)
        {
            return -1;
        }

        public double evalAt(double val1, double val2)
        {
            return -1;
        }

        public double evalAt(double val1, double val2, double val3)
        {
            return -1;
        }

        public Expression<Func<double, double>> getExpressionEquation()
        {
            return equat;
        }

        public String getExpressionString()
        {
            return express;
        }
    }
}
